package com.finance.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.finance.entity.TicketOrder;
import com.finance.mapper.TicketOrderMapper;
import com.finance.service.TicketOrderService;
import com.finance.vo.TicketOrderVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * C01
 * 影票订单数据Service实现类
 */
@Slf4j
@Service
public class TicketOrderServiceImpl extends ServiceImpl<TicketOrderMapper, TicketOrder> implements TicketOrderService {

    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm");

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int saveTicketOrder(List<Map<String, String>> records) {
        return saveTicketOrder(records, null, false, null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int saveTicketOrder(List<Map<String, String>> records, String searchDate, boolean forceUpdate) {
        return saveTicketOrder(records, searchDate, forceUpdate, null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int saveTicketOrder(List<Map<String, String>> records, String searchDate, boolean forceUpdate, String cinemaId) {
        if (records == null || records.isEmpty()) {
            log.warn("No records to process for C01 data");
            return 0;
        }

        // 如果提供了searchDate和cinemaId，检查是否需要删除旧数据
        if (searchDate != null && cinemaId != null) {
            LambdaQueryWrapper<TicketOrder> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(TicketOrder::getSearchDate, searchDate)
                    .eq(TicketOrder::getCinemaId, cinemaId);
            long count = count(queryWrapper);
            
            if (count > 0) {
                if (!forceUpdate) {
                    log.info("Data for searchDate {} and cinemaId {} already exists and forceUpdate is false, skipping", searchDate, cinemaId);
                    return 0;
                }
                // 删除旧数据
                remove(queryWrapper);
                log.info("Deleted {} existing records for searchDate {} and cinemaId {}", count, searchDate, cinemaId);
            }
        }

        List<TicketOrder> orderList = new ArrayList<>();
        for (Map<String, String> record : records) {
            try {
                //影院名称,影院编码,销售类型,销售时间,影票数,票价,服务费,网络代售费,支付金额,支付工具
                // 先将CSV数据转换为VO对象
                TicketOrderVO ticketOrderVO = new TicketOrderVO();
                if (StringUtils.hasText(record.get("影院名称"))) {
                    ticketOrderVO.setCinemaName(record.get("影院名称"));
                }
                if (StringUtils.hasText(record.get("影院编码"))) {
                    ticketOrderVO.setCinemaCode(record.get("影院编码"));
                }
                if (StringUtils.hasText(record.get("销售类型"))) {
                    ticketOrderVO.setSaleType(record.get("销售类型"));
                }
                
                // 转换日期时间类型
                String saleTimeStr = record.get("销售时间");
                if (StringUtils.hasText(saleTimeStr)) {
                    ticketOrderVO.setSaleTime(LocalDateTime.parse(saleTimeStr, DATE_TIME_FORMATTER));
                }
                
                // 转换数字类型
                String ticketCountStr = record.get("影票数");
                if (StringUtils.hasText(ticketCountStr)) {
                    ticketOrderVO.setTicketCount(Integer.parseInt(ticketCountStr));
                }
                
                String ticketPriceStr = record.get("票价");
                if (StringUtils.hasText(ticketPriceStr)) {
                    ticketOrderVO.setTicketPrice(new BigDecimal(ticketPriceStr));
                }
                
                String serviceFeeStr = record.get("服务费");
                if (StringUtils.hasText(serviceFeeStr)) {
                    ticketOrderVO.setServiceFee(new BigDecimal(serviceFeeStr));
                }
                
                String networkFeeStr = record.get("网络代售费");
                if (StringUtils.hasText(networkFeeStr)) {
                    ticketOrderVO.setNetworkFee(new BigDecimal(networkFeeStr));
                }
                
                String payAmountStr = record.get("支付金额");
                if (StringUtils.hasText(payAmountStr)) {
                    ticketOrderVO.setPayAmount(new BigDecimal(payAmountStr));
                }
                
                if (StringUtils.hasText(record.get("支付工具"))) {
                    ticketOrderVO.setPaymentTool(record.get("支付工具"));
                }
                // 支付工具编码,最低票价,补贴方,优惠信息,优惠金额,第三方优惠信息,第三方优惠金额,活动编码,活动名称
                if (StringUtils.hasText(record.get("支付工具编码"))) {
                    ticketOrderVO.setPaymentToolCode(record.get("支付工具编码"));
                }
                String minTicketPriceStr = record.get("最低票价");
                if (StringUtils.hasText(minTicketPriceStr)) {
                    ticketOrderVO.setMinTicketPrice(new BigDecimal(minTicketPriceStr));
                }
                if (StringUtils.hasText(record.get("补贴方"))) {
                    ticketOrderVO.setSubsidyParty(record.get("补贴方"));
                }
                if (StringUtils.hasText(record.get("优惠信息"))) {
                    ticketOrderVO.setDiscountInfo(record.get("优惠信息"));
                }
                String discountAmountStr = record.get("优惠金额");
                if (StringUtils.hasText(discountAmountStr)) {
                    ticketOrderVO.setDiscountAmount(new BigDecimal(discountAmountStr));
                }
                if (StringUtils.hasText(record.get("第三方优惠信息"))) {
                    ticketOrderVO.setThirdPartyDiscountInfo(record.get("第三方优惠信息"));
                }
                String thirdPartyDiscountAmountStr = record.get("第三方优惠金额");
                if (StringUtils.hasText(thirdPartyDiscountAmountStr)) {
                    ticketOrderVO.setThirdPartyDiscountAmount(new BigDecimal(thirdPartyDiscountAmountStr));
                }
                if (StringUtils.hasText(record.get("活动编码"))) {
                    ticketOrderVO.setActivityCode(record.get("活动编码"));
                }
                if (StringUtils.hasText(record.get("活动名称"))) {
                    ticketOrderVO.setActivityName(record.get("活动名称"));
                }
                // 销售渠道,销售渠道编码,操作员,票号,影片名称,影厅名称,放映日期,放映时间,座位号
                if (StringUtils.hasText(record.get("销售渠道"))) {
                    ticketOrderVO.setSaleChannel(record.get("销售渠道"));
                }
                if (StringUtils.hasText(record.get("销售渠道编码"))) {
                    ticketOrderVO.setSaleChannelCode(record.get("销售渠道编码"));
                }
                if (StringUtils.hasText(record.get("操作员"))) {
                    ticketOrderVO.setTicketSeller(record.get("操作员"));
                }
                if (StringUtils.hasText(record.get("票号"))) {
                    ticketOrderVO.setTicketNo(record.get("票号"));
                }
                if (StringUtils.hasText(record.get("影片名称"))) {
                    ticketOrderVO.setMovieName(record.get("影片名称"));
                }
                if (StringUtils.hasText(record.get("影厅名称"))) {
                    ticketOrderVO.setHallName(record.get("影厅名称"));
                }
                
                // 转换日期时间类型
                String showDateStr = record.get("放映日期");
                if (StringUtils.hasText(showDateStr)) {
                    ticketOrderVO.setScreeningDate(LocalDate.parse(showDateStr, DATE_FORMATTER));
                }
                
                String showTimeStr = record.get("放映时间");
                if (StringUtils.hasText(showTimeStr)) {
                    ticketOrderVO.setScreeningTime(LocalTime.parse(showTimeStr, TIME_FORMATTER));
                }
                
                if (StringUtils.hasText(record.get("座位号"))) {
                    ticketOrderVO.setSeatNo(record.get("座位号"));
                }
                // 票类,售订单号,退订单号,第三方订单号,影院所在区域,影票打印时间,支付使用券模版名称,退票渠道编码
                if (StringUtils.hasText(record.get("票类"))) {
                    ticketOrderVO.setTicketType(record.get("票类"));
                }
                if (StringUtils.hasText(record.get("售订单号"))) {
                    ticketOrderVO.setSaleOrderNo(record.get("售订单号"));
                }
                if (StringUtils.hasText(record.get("退订单号"))) {
                    ticketOrderVO.setRefundOrderNo(record.get("退订单号"));
                }
                if (StringUtils.hasText(record.get("第三方订单号"))) {
                    ticketOrderVO.setThirdPartyOrderNo(record.get("第三方订单号"));
                }
                if (StringUtils.hasText(record.get("影院所在区域"))) {
                    ticketOrderVO.setCinemaArea(record.get("影院所在区域"));
                }
                
                String printTimeStr = record.get("影票打印时间");
                if (StringUtils.hasText(printTimeStr)) {
                    ticketOrderVO.setTicketPrintTime(LocalDateTime.parse(printTimeStr, DATE_TIME_FORMATTER));
                }
                
                if (StringUtils.hasText(record.get("支付使用券模版名称"))) {
                    ticketOrderVO.setPaymentCouponTemplateName(record.get("支付使用券模版名称"));
                }
                if (StringUtils.hasText(record.get("退票渠道编码"))) {
                    ticketOrderVO.setRefundChannelCode(record.get("退票渠道编码"));
                }
                // 退票渠道名称,会员卡卡号,优惠券码,影票打印员工号,支付序列,影厅编码,影片编码,券模版编码,支付使用卡名称
                if (StringUtils.hasText(record.get("退票渠道名称"))) {
                    ticketOrderVO.setRefundChannelName(record.get("退票渠道名称"));
                }
                if (StringUtils.hasText(record.get("会员卡卡号"))) {
                    ticketOrderVO.setMemberCardNo(record.get("会员卡卡号"));
                }
                if (StringUtils.hasText(record.get("优惠券码"))) {
                    ticketOrderVO.setCouponCode(record.get("优惠券码"));
                }
                if (StringUtils.hasText(record.get("影票打印员工号"))) {
                    ticketOrderVO.setTicketPrintEmployeeNo(record.get("影票打印员工号"));
                }
                if (StringUtils.hasText(record.get("支付序列"))) {
                    ticketOrderVO.setPaymentSequence(record.get("支付序列"));
                }
                if (StringUtils.hasText(record.get("影厅编码"))) {
                    ticketOrderVO.setHallCode(record.get("影厅编码"));
                }
                if (StringUtils.hasText(record.get("影片编码"))) {
                    ticketOrderVO.setMovieCode(record.get("影片编码"));
                }
                if (StringUtils.hasText(record.get("券模版编码"))) {
                    ticketOrderVO.setCouponTemplateCode(record.get("券模版编码"));
                }
                if (StringUtils.hasText(record.get("支付使用卡名称"))) {
                    ticketOrderVO.setPaymentCardName(record.get("支付使用卡名称"));
                }
                // 影城所属区域编码,销售员工号,取票员,会员ID,手机号,场次号,商户订单号,第三方支付流水号,影片国别,影片语言,影厅类型,其它费用,活动类型
                if (StringUtils.hasText(record.get("影城所属区域编码"))) {
                    ticketOrderVO.setCinemaAreaCode(record.get("影城所属区域编码"));
                }
                if (StringUtils.hasText(record.get("销售员工号"))) {
                    ticketOrderVO.setSalesEmployeeNo(record.get("销售员工号"));
                }
                if (StringUtils.hasText(record.get("取票员"))) {
                    ticketOrderVO.setTicketCollector(record.get("取票员"));
                }
                if (StringUtils.hasText(record.get("会员ID"))) {
                    ticketOrderVO.setMemberId(record.get("会员ID"));
                }
                if (StringUtils.hasText(record.get("手机号"))) {
                    ticketOrderVO.setMobilePhone(record.get("手机号"));
                }
                if (StringUtils.hasText(record.get("场次号"))) {
                    ticketOrderVO.setScreeningNo(record.get("场次号"));
                }
                if (StringUtils.hasText(record.get("商户订单号"))) {
                    ticketOrderVO.setMerchantOrderNo(record.get("商户订单号"));
                }
                if (StringUtils.hasText(record.get("第三方支付流水号"))) {
                    ticketOrderVO.setThirdPartyPaymentNo(record.get("第三方支付流水号"));
                }
                if (StringUtils.hasText(record.get("影片国别"))) {
                    ticketOrderVO.setMovieCountry(record.get("影片国别"));
                }
                if (StringUtils.hasText(record.get("影片语言"))) {
                    ticketOrderVO.setMovieLanguage(record.get("影片语言"));
                }
                if (StringUtils.hasText(record.get("影厅类型"))) {
                    ticketOrderVO.setHallType(record.get("影厅类型"));
                }
                if (StringUtils.hasText(record.get("卡类型"))) {
                    ticketOrderVO.setCardType(record.get("卡类型"));
                }

                String otherFeeStr = record.get("其它费用");
                if (StringUtils.hasText(otherFeeStr)) {
                    ticketOrderVO.setOtherFees(new BigDecimal(otherFeeStr));
                }
                
                if (StringUtils.hasText(record.get("活动类型"))) {
                    ticketOrderVO.setCardType(record.get("活动类型"));
                }
                // 是否票补活动,发卡影城编码,发卡影城名称,发券影城编码,发券影城名称,退票手续费金额

                // 将VO对象转换为实体对象
                TicketOrder ticketOrder = new TicketOrder();
                BeanUtils.copyProperties(ticketOrderVO, ticketOrder);
                // 设置searchDate和cinemaId
                if (searchDate != null) {
                    ticketOrder.setSearchDate(searchDate);
                }
                if (cinemaId != null) {
                    ticketOrder.setCinemaId(cinemaId);
                }
                orderList.add(ticketOrder);
            } catch (Exception e) {
                log.error("Error processing ticket order record: {}", record, e);
            }
        }

        try {
            if (!orderList.isEmpty()) {
                return saveBatch(orderList) ? orderList.size() : 0;
            }
            return 0;
        } catch (Exception e) {
            log.error("批量保存C01商品订单数据失败", e);
            throw e;
        }
    }
} 